﻿using System;
using System.Collections.Generic;
using Allegro.MathInterface;

namespace Allegro.MathLib
{
    /// <summary>
    /// Root finding interface that solves an equation f(x) = 0
    /// without derivative values
    /// </summary>
    public interface IRootFinder
    {
        /// <summary>
        /// 
        /// </summary>
        /// <param name="f"></param>
        /// <param name="x1"></param>
        /// <param name="x2"></param>
        /// <param name="eps"></param>
        /// <returns></returns>
        double FindRoot(Func<double,double> f, double x1, double x2, double eps);
    }

    /// <summary>
    /// Root finding interface that solves an equation f(x) = 0 using 
    /// information about first derivatives f'(x)
    /// </summary>
    public interface IDiffRootFinder
    {
        /// <summary>
        /// Find the root of the equation f(x) in the interval x1 &lt;= x &lt;= x2
        /// using the derivative f'(x) in addition to the function value f(x)
        /// </summary>
        /// <param name="f"></param>
        /// <param name="df"></param>
        /// <param name="x1"></param>
        /// <param name="x2"></param>
        /// <param name="eps"></param>
        /// <returns></returns>
        double FindRoot(Func<double, double> f, Func<double, double> df, double x1, double x2, double eps);
    }

    /// <summary>
    /// Solve the vector equation f = 0 within a region of the vector space constrained by
    /// x1[i] &lt;= x[i] &lt;= x2[i]
    /// </summary>
    //public interface IEquationSolver
    //{
    //    /// <summary>
    //    /// Solve the vector equation f = 0
    //    /// </summary>
    //    /// <param name="f"></param>
    //    /// <param name="x1"></param>
    //    /// <param name="x2"></param>
    //    /// <param name="eps"></param>
    //    /// <returns></returns>
    //    void FindRoot(VectorFunction f, double[] x1, double[] x2, double eps, ref double[] root);   
    //}

    /// <summary>
    /// Solve the vector equation F = 0 within a region of the vector space constrained by
    /// x1[i] &lt;= x[i] &lt;= x2[i]
    /// </summary>
    public interface IEquationSetSolver
    {
        /// <summary>
        /// Convergence ctiterion in function value
        /// </summary>
        double ToleranceF { get; set; }

        /// <summary>
        /// Convergence criterion in coordinate x
        /// </summary>
        double ToleranceX { get; set; }

        /// <summary>
        /// Solve the vector equation f = 0 using numerical differentiation to compute the
        /// Jacobian matrix
        /// </summary>
        /// <param name="f">Vector</param>
        /// <param name="x0">Initial guess</param>
        /// <param name="steps">Initial steps used for numerical differentiation</param>
        /// <param name="root">Resulting root</param>
        /// <returns></returns>
        void FindRoot(VectorMap f, double[] x0, double[] steps, ref double[] root);

        /// <summary>
        /// Solve the vector equation f = 0. The caller must supply a delegate
        /// that provides the Jacobian matrix
        /// </summary>
        /// <param name="f">Vector</param>
        /// <param name="jacobi">Delegate for computing the jacobi matrix</param>
        /// <param name="x0">Initial guess</param>
        /// <param name="root">Resulting root</param>
        /// <returns></returns>
        void FindRoot(VectorMap f, VectorMatrixMap jacobi, double[] x0, ref double[] root);
    }
}
